//! 操作数解析实现
//! 
//! 解析各种类型的操作数：立即数、寄存器、内存地址、标签

use crate::ast::*;
use crate::error::{AssemblerError, Result};
use crate::lexer::Token;
use super::core::Parser;

pub trait OperandParser {
    fn parse_operand(&mut self) -> Result<Operand>;
    fn parse_jump_operand(&mut self) -> Result<Operand>;
    fn parse_memory_operand(&mut self, base: Option<String>) -> Result<Operand>;
    fn is_register(&self, name: &str) -> bool;
}

impl OperandParser for Parser {
    /// 检查是否为寄存器名称
    fn is_register(&self, name: &str) -> bool {
        matches!(name, 
            "累加器" | "计数" | "数据" | "基址" | 
            "栈指针" | "基址指针" | "源索引" | "目标索引"
        )
    }

    /// 解析跳转指令的操作数
    fn parse_jump_operand(&mut self) -> Result<Operand> {
        match &self.current_token {
            Token::Number(n) => {
                let value = *n;
                self.advance()?;
                Ok(Operand::Immediate(value))
            }
            Token::Minus => {
                // 处理负数：-数字
                self.advance()?; // 消费减号
                match &self.current_token {
                    Token::Number(n) => {
                        let value = -*n; // 取负值
                        self.advance()?;
                        Ok(Operand::Immediate(value))
                    }
                    _ => {
                        let (line, column) = self.lexer.position();
                        Err(AssemblerError::ParseError {
                            message: "减号后期望数字".to_string(),
                            line,
                            column,
                        })
                    }
                }
            }
            Token::Identifier(name) => {
                let name = name.clone();
                self.advance()?;
                // 跳转指令中的标识符是标签引用
                Ok(Operand::Label(name))
            }
            _ => {
                let (line, column) = self.lexer.position();
                Err(AssemblerError::ParseError {
                    message: "期望标签或立即数".to_string(),
                    line,
                    column,
                })
            }
        }
    }

    /// 解析操作数
    fn parse_operand(&mut self) -> Result<Operand> {
        match &self.current_token {
            Token::Number(n) => {
                let value = *n;
                self.advance()?;
                Ok(Operand::Immediate(value))
            }
            Token::Minus => {
                // 处理负数：-数字
                self.advance()?; // 消费减号
                match &self.current_token {
                    Token::Number(n) => {
                        let value = -*n; // 取负值
                        self.advance()?;
                        Ok(Operand::Immediate(value))
                    }
                    _ => {
                        let (line, column) = self.lexer.position();
                        Err(AssemblerError::ParseError {
                            message: "减号后期望数字".to_string(),
                            line,
                            column,
                        })
                    }
                }
            }
            Token::Identifier(name) => {
                // 可能是寄存器或内存地址的开始
                let name = name.clone();
                self.advance()?;

                // 检查是否是内存地址 [xxx]
                if self.check_token(&Token::LeftBracket) {
                    self.parse_memory_operand(Some(name))
                } else if self.is_register(&name) {
                    // 是寄存器
                    Ok(Operand::Register(name))
                } else {
                    // 不是寄存器，可能是标签（但在非跳转指令中，这是错误）
                    let (line, column) = self.lexer.position();
                    Err(AssemblerError::ParseError {
                        message: format!(
                            "标识符 '{}' 不是有效的寄存器。在非跳转指令中，标签只能用于跳转指令",
                            name
                        ),
                        line,
                        column,
                    })
                }
            }
            Token::LeftBracket => {
                // 内存地址，没有基址寄存器
                self.parse_memory_operand(None)
            }
            _ => {
                let (line, column) = self.lexer.position();
                Err(AssemblerError::ParseError {
                    message: "期望操作数".to_string(),
                    line,
                    column,
                })
            }
        }
    }

    /// 解析内存操作数
    fn parse_memory_operand(&mut self, base: Option<String>) -> Result<Operand> {
        self.expect_token(&Token::LeftBracket)?;

        let mut mem_operand = MemoryOperand {
            base: base.clone(),
            index: None,
            scale: None,
            displacement: None,
        };

        // 解析内存地址表达式
        // 格式: [base + index * scale + displacement]
        // 或: [base + displacement]
        // 或: [displacement]

        // 如果已经有基址寄存器，继续解析
        if base.is_some() {
            // 可能有 + index * scale 或 + displacement 或 - displacement
            // 或 + index + displacement
            if self.check_token(&Token::Plus) {
                self.advance()?;
                // 解析索引或偏移
                if let Token::Identifier(idx_name) = &self.current_token {
                    let idx_name = idx_name.clone();
                    self.advance()?;
                    
                    // 检查是否有 * scale
                    if self.check_token(&Token::Asterisk) {
                        self.advance()?;
                        if let Token::Number(scale) = &self.current_token {
                            mem_operand.index = Some(idx_name);
                            mem_operand.scale = Some(*scale as u8);
                            self.advance()?;
                        }
                    } else {
                        // 可能是索引寄存器，后面可能还有 + displacement
                        mem_operand.index = Some(idx_name);
                        
                        // 检查是否还有 + displacement
                        if self.check_token(&Token::Plus) {
                            self.advance()?;
                            if let Token::Number(disp) = &self.current_token {
                                mem_operand.displacement = Some(*disp);
                                self.advance()?;
                            } else if self.check_token(&Token::Minus) {
                                self.advance()?;
                                if let Token::Number(disp) = &self.current_token {
                                    mem_operand.displacement = Some(-*disp);
                                    self.advance()?;
                                }
                            }
                        }
                    }
                } else if let Token::Number(disp) = &self.current_token {
                    mem_operand.displacement = Some(*disp);
                    self.advance()?;
                }
            } else if self.check_token(&Token::Minus) {
                // 处理负偏移量
                self.advance()?;
                if let Token::Number(disp) = &self.current_token {
                    mem_operand.displacement = Some(-*disp);
                    self.advance()?;
                }
            }
        } else {
            // 解析第一个部分
            match &self.current_token {
                Token::Identifier(name) => {
                    let name = name.clone();
                    self.advance()?;
                    
                    if self.check_token(&Token::Plus) {
                        self.advance()?;
                        // 可能是索引或偏移
                        if let Token::Identifier(idx_name) = &self.current_token {
                            let idx_name = idx_name.clone();
                            self.advance()?;
                            
                            if self.check_token(&Token::Asterisk) {
                                self.advance()?;
                                if let Token::Number(scale) = &self.current_token {
                                    mem_operand.base = Some(name);
                                    mem_operand.index = Some(idx_name);
                                    mem_operand.scale = Some(*scale as u8);
                                    self.advance()?;
                                }
                            } else {
                                // 可能是索引寄存器，后面可能还有 + displacement
                                mem_operand.base = Some(name);
                                mem_operand.index = Some(idx_name);
                                
                                // 检查是否还有 + displacement
                                if self.check_token(&Token::Plus) {
                                    self.advance()?;
                                    if let Token::Number(disp) = &self.current_token {
                                        mem_operand.displacement = Some(*disp);
                                        self.advance()?;
                                    } else if self.check_token(&Token::Minus) {
                                        self.advance()?;
                                        if let Token::Number(disp) = &self.current_token {
                                            mem_operand.displacement = Some(-*disp);
                                            self.advance()?;
                                        }
                                    }
                                } else if self.check_token(&Token::Minus) {
                                    self.advance()?;
                                    if let Token::Number(disp) = &self.current_token {
                                        mem_operand.displacement = Some(-*disp);
                                        self.advance()?;
                                    }
                                }
                            }
                        } else if let Token::Number(disp) = &self.current_token {
                            mem_operand.base = Some(name);
                            mem_operand.displacement = Some(*disp);
                            self.advance()?;
                        }
                    } else if self.check_token(&Token::Minus) {
                        // 处理负偏移量
                        self.advance()?;
                        if let Token::Number(disp) = &self.current_token {
                            mem_operand.base = Some(name);
                            mem_operand.displacement = Some(-*disp);
                            self.advance()?;
                        }
                    } else {
                        mem_operand.base = Some(name);
                    }
                }
                Token::Number(disp) => {
                    mem_operand.displacement = Some(*disp);
                    self.advance()?;
                }
                _ => {}
            }
        }

        self.expect_token(&Token::RightBracket)?;
        Ok(Operand::Memory(mem_operand))
    }
}

